package com.hframe.database;

import java.util.ArrayList;


/**
 * 数据库线程池管理
 *
 * @author heqian
 */
public class DatabasePool {
    private ArrayList<Pool> pools = new ArrayList<>();
    private static DatabasePool interfac = null;
    private boolean isShutdown = false;

    public static DatabasePool get() {
        if (null == interfac)
            interfac = new DatabasePool();
        return interfac;
    }

    public static void shutdown() {
        if (null != interfac) {
            for (Pool p : interfac.pools) {
                p.colse();
            }
            interfac.pools.clear();
            interfac.isShutdown = true;
        }
    }

    public Database getDatabase(DatabaseConfig config) {
        for (Pool p : pools) {
            if (p.config == config) {
                return p.getDatabase();
            }
        }

        Pool p = new Pool(this, config);
        synchronized (pools) {
            pools.add(p);
        }
        return p.getDatabase();
    }

    public void close() {
        for (Pool p : pools) {
            p.colse();
        }
        pools.clear();
    }

    static class Pool {
        DatabasePool databasePool = null;
        DatabaseConfig config = null;
        ArrayList<Database> datas = new ArrayList<>();
        Integer count = 0;
        int maxCount = 1;

        public int getCount() {
            synchronized (count) {
                return count;
            }
        }

        public void addCount(int count) {
            synchronized (this.count) {
                this.count += count;
                System.out.println(config.TableName().get() + " 计数 " + count + "   " + this.count);
            }
        }

        public Pool(DatabasePool databasePool, DatabaseConfig config) {
            this.databasePool = databasePool;
            this.config = config;
            this.maxCount = config.ThreadCount().get();
            if (0 >= this.maxCount)
                this.maxCount = 1;
        }

        public void colse() {
            for (Database item : datas) {
            //    item.closeStatement();
            //   item.closeConnection();
            }
        }

        public Database getDatabase() {
            synchronized (this) {
                while (getCount() >= maxCount && !databasePool.isShutdown) {
                    try {
                        wait(50L);
                    } catch (Exception e) {
                    }
                }
                addCount(1);
                return getData();
            }
        }

        private Database getData() {
            for (Database item : datas) {
                if (!item.isOccupy())
                    return item;
            }

            Database item = config.getDatabase();
            item.setThread(true);
            item.setOccupy(true);
            item.setPool(this);
            datas.add(item);
            return item;
        }
    }
}
